﻿using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using GDGeek;
using Mirror;
using UnityEngine;

namespace Shows_3D
{
    public class ConnectionManager : Singleton<ConnectionManager>
    {
        [SerializeField] private GameObject objMirror;
        [SerializeField] private GameObject objCustomServiceList;
        [SerializeField] private GameObject objStartHost;
        [SerializeField] private GameObject objStopHost;
        [SerializeField] private GameObject objFree;
        [SerializeField] private GameObject objClientChat;
        [SerializeField] private GameObject objDiscovery;
        [SerializeField] private GameObject objDiscovering;
        [SerializeField] private GameObject objStopDiscovery;
        [SerializeField] private GameObject objDisconnect;
        private readonly FSM _fsm = new FSM();

        private void Awake()
        {
            //注册 发现服务器 事件
            objMirror.GetComponent<Shows3DNetworkDiscovery>().OnServerFound
                .AddListener(delegate(Shows3DServerResponse response)
                {
                    Debug.Log("server on found!");
                    PostToFsm("fundHost", response);
                });
            //注册 客户端连接 事件
            objMirror.GetComponent<Shows3DNetworkManager>().onServerConnectEvent.AddListener(
                delegate(NetworkConnection connection) { PostToFsm("clientConnect", connection); });
            //注册 客户端断开 事件
            objMirror.GetComponent<Shows3DNetworkManager>().onServerDisconnectEvent.AddListener(
                delegate(NetworkConnection connection) { PostToFsm("clientDisconnect", connection); });
        }

        // Start is called before the first frame update
        private void Start()
        {
            _fsm.addState("standAlone", OnStandAlone());
            _fsm.addState("host", OnHost());
            _fsm.addState("client", OnClient());

            _fsm.init("standAlone");
        }

        private StateBase OnStandAlone()
        {
            State state = new State();
            state.onStart += delegate
            {
                objDiscovery.SetActive(true);
                objStartHost.SetActive(true);
            };
            state.onOver += delegate
            {
                objDiscovery.SetActive(false);
                objStartHost.SetActive(false);
            };
            state.addAction("startHost", "host");
            state.addAction("discovery", "client");
            return state;
        }

        private StateBase OnHost()
        {
            State state = new State();
            state.onStart += delegate
            {
                objFree.SetActive(true); 
                //objStopHost.SetActive(true);
            };
            state.addAction("clientConnect", delegate(FSMEvent evt)
            {
                objFree.SetActive(false);
                //objStopHost.SetActive(false);
                objClientChat.SetActive(true);
                NetworkConnection info = (NetworkConnection) evt.obj;
                objClientChat.GetComponent<ClientChat>().ClientName = info.address;
            });
            state.addAction("clientDisconnect", delegate(FSMEvent evt)
            {
                objFree.SetActive(true);
                //objStopHost.SetActive(true);
                objClientChat.SetActive(false);
            });
            state.addAction("stopHost", "standAlone");
            
            state.onOver += delegate
            {
                objFree.SetActive(false);
                //objStopHost.SetActive(false);
                objClientChat.SetActive(false);
            };
            return state;
        }

        private StateBase OnClient()
        {
            State state = new State();
            state.onStart += delegate
            {
                objDiscovering.SetActive(true);
                objStopDiscovery.SetActive(true);
            };
            state.addAction("fundHost", delegate(FSMEvent evt)
            {
                Debug.Log("fundHost");
                objDiscovering.SetActive(false);
                objCustomServiceList.SetActive(true);
            });
            state.addAction("connect", delegate(FSMEvent evt)
            {
                Debug.Log("connect");
                objDisconnect.SetActive(true);
                objCustomServiceList.SetActive(false);
                objStopDiscovery.SetActive(false);

            });
            state.addAction("disconnect", delegate(FSMEvent evt)
            {
                Debug.Log("disconnect");
                objCustomServiceList.GetComponent<CustomServiceList>().Clear();
                return "standAlone";
            }); 
            state.addAction("stopDiscovery", delegate(FSMEvent evt)
            {
                Debug.Log("stopDiscovery");
                objCustomServiceList.GetComponent<CustomServiceList>().Clear();
                objStopDiscovery.SetActive(false);
                return "standAlone";
            });
            state.onOver += delegate
            {
                objDiscovering.SetActive(false);
                objDisconnect.SetActive(false);
                objCustomServiceList.SetActive(false);
            };
            return state;
        }

        public void PostToFsm(string evt)
        {
            _fsm.post(evt);
        }

        public void PostToFsm(string evt, Shows3DServerResponse obj)
        {
            _fsm.post(evt, obj);
        }

        public void PostToFsm(string evt, NetworkConnection obj)
        {
            _fsm.post(evt, obj);
        }
    }
}